package com.ok.common.base

import android.os.Bundle
import android.view.*
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.DialogFragment
import androidx.viewbinding.ViewBinding
import com.ok.common.common.Constants
import com.ok.common.R
import com.ok.common.utils.EventUtils
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.reflect.ParameterizedType

abstract class BaseDialogFragment<VB : ViewBinding> : DialogFragment(), View.OnClickListener {

    private var _binding: VB? = null

    protected val mBinding get() = _binding!!

    protected var mActivity: BaseActivity<*>? = null

    private var isFirst = true

    private var lastButtonId = -1

    private var lastClickTime = 0L

    @LayoutRes
    protected open val layoutId = 0

    open fun getBaseActivity(): BaseActivity<*>? {
        return this.activity as BaseActivity<*>?
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mActivity = getBaseActivity()
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog?.setCanceledOnTouchOutside(true)
        dialog?.setCancelable(true)
        val window = dialog!!.window
        val lp = window!!.attributes
        lp.gravity = Gravity.BOTTOM
        lp.width = WindowManager.LayoutParams.MATCH_PARENT
        window.attributes = lp
        if (isRegisterEvent) {
            EventUtils.register(this)
        }
        return initBinding(inflater, container)
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        initView(arguments)
        initImmersionBar()
        initObserve()
        initData()
        initListener()
    }

    abstract fun initView(args: Bundle?)

    open fun initImmersionBar() {
//        immersionBar()
    }

    open fun initData() {}

    open fun initListener() {}

    open fun initObserve() {}

    open fun lazyLoad() {}

    //防止多次点击的点击事件
    open fun mClick(v: View?) {}

    override fun onStart() {
        super.onStart()
        dialog!!.window!!.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        dialog!!.window!!.setBackgroundDrawableResource(android.R.color.transparent)
    }

    override fun onResume() {
        super.onResume()
    }

    open var isRegisterEvent = false

    @Subscribe(threadMode = ThreadMode.MAIN)
    open fun onEventBusCome(event: BaseEvent?) {
        if (event != null) {
            handleEvent(event)
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    open fun onStickyEventBusCome(event: BaseEvent?) {
        if (event != null) {
            handleStickyEvent(event)
        }
    }

    open fun handleEvent(event: BaseEvent) {}

    open fun handleStickyEvent(event: BaseEvent) {}

    protected fun showLoading(text: String = getString(R.string.loading)) {
        getBaseActivity()?.showLoading(text)
    }

    protected fun dismissLoading() {
        getBaseActivity()?.dismissLoading()
    }

    fun finish() {
        mActivity?.finish()
    }

    override fun onClick(v: View?) {
        val currentButtonId = v?.id
        if (!fastClick() && (lastButtonId == currentButtonId)) {
            return
        }
        if (currentButtonId != null) {
            lastButtonId = currentButtonId
        }
        mClick(v)
    }

    private fun fastClick(): Boolean {
        if (System.currentTimeMillis() - lastClickTime <= Constants.MIN_CLICK_DELAY_TIME) {
            return false
        }
        lastClickTime = System.currentTimeMillis()
        return true
    }

    private fun initBinding(inflater: LayoutInflater, container: ViewGroup?): View {
        val type = javaClass.genericSuperclass
        if (type is ParameterizedType) {
            val cls = type.actualTypeArguments.map { it as Class<*> }
                .first { ViewBinding::class.java.isAssignableFrom(it) }
            return when {
                ViewDataBinding::class.java.isAssignableFrom(cls) && cls != ViewDataBinding::class.java -> {
                    if (layoutId == 0) throw IllegalArgumentException("Using DataBinding requires overriding method layoutId")
                    _binding = DataBindingUtil.inflate(inflater, layoutId, container, false)
                    (mBinding as ViewDataBinding).lifecycleOwner = this
                    mBinding.root
                }

                ViewBinding::class.java.isAssignableFrom(cls) && cls != ViewBinding::class.java -> {
                    cls.getDeclaredMethod("inflate", LayoutInflater::class.java).let {
                        @Suppress("UNCHECKED_CAST")
                        _binding = it.invoke(null, inflater) as VB
                        mBinding.root
                    }
                }

                else -> {
                    if (layoutId == 0) throw IllegalArgumentException("If you don't use ViewBinding, you need to override method layoutId")
                    inflater.inflate(layoutId, container, false)
                }
            }
        } else throw IllegalArgumentException("Generic error")
    }


    override fun onDestroy() {
        super.onDestroy()
        if (isRegisterEvent) {
            EventUtils.unregister(this)
        }
    }

}